package com.stars.easyms.datasource.monitor;

import com.stars.easyms.base.constant.EasyMsCommonConstants;
import com.stars.easyms.monitor.MonitorRequestHandler;
import com.stars.easyms.datasource.*;
import com.stars.easyms.datasource.common.EasyMsDataSourceConstant;

import java.util.*;

/**
 * <p>className: EasyMsDatasourceMonitorRequestHandler</p>
 * <p>description: EasyMs数据源监控类</p>
 *
 * @author guoguifang
 * @date 2019-11-20 15:39
 * @since 1.4.0
 */
public final class EasyMsDatasourceMonitorRequestHandler implements MonitorRequestHandler {

    @Override
    public Map<String, Object> getMonitorInfo() {
        final Map<String, Object> map = new LinkedHashMap<>();
        EasyMsMultiDataSource easyMsMultiDataSource = EasyMsDataSourceFactory.getEasyMsMultiDataSource();
        Map<String, EasyMsMasterSlaveDataSource> dataSources = easyMsMultiDataSource.getDataSources();
        dataSources.forEach((datasourceName, easyMsMasterSlaveDataSource) -> {
            Map<String, Object> easyMsMasterSlaveDataSourceMap = new LinkedHashMap<>();
            easyMsMasterSlaveDataSourceMap.put("数据库类型", easyMsMasterSlaveDataSource.getDatabaseType().getDbType());
            EasyMsDataSourceSet masterDataSourceSet = easyMsMasterSlaveDataSource.getMasterDataSourceSet();
            if (!masterDataSourceSet.isEmpty()) {
                easyMsMasterSlaveDataSourceMap.put("主数据源负载均衡策略", easyMsMasterSlaveDataSource.getMasterLoadBalancer().getCode());
                easyMsMasterSlaveDataSourceMap.put("主数据源列表", getDataSourcesMap(masterDataSourceSet));
            }
            EasyMsDataSourceSet slaveDataSourceSet = easyMsMasterSlaveDataSource.getSlaveDataSourceSet();
            if (!slaveDataSourceSet.isEmpty()) {
                easyMsMasterSlaveDataSourceMap.put("从数据源负载均衡策略", easyMsMasterSlaveDataSource.getSlaveLoadBalancer().getCode());
                easyMsMasterSlaveDataSourceMap.put("从数据源列表", getDataSourcesMap(slaveDataSourceSet));
            }
            map.put(EasyMsDataSourceConstant.DEFAULT_DATASOURCE_NAME.equals(datasourceName) ? EasyMsCommonConstants.DEFAULT : datasourceName, easyMsMasterSlaveDataSourceMap);
        });
        return map;
    }

    private Map<String, Object> getDataSourcesMap(EasyMsDataSourceSet dataSourceSet) {
        Map<String, Object> dataSourcesMap = new LinkedHashMap<>();
        int index = 1;
        for (EasyMsDataSource easyMsDataSource : dataSourceSet) {
            Map<String, Object> dataSourceMap = new LinkedHashMap<>();
            dataSourceMap.put("数据源类型", easyMsDataSource.getDataSource().getClass().getName());
            dataSourceMap.put("连接地址", easyMsDataSource.getAbbrUrl());
            dataSourceMap.put("已完成数量", easyMsDataSource.getExecutedCount());
            Map<String, Object> currentExecuteSqlMap = getCurrentExecuteSqlMap(easyMsDataSource.getCurrentExecuteSqlList());
            dataSourceMap.put("正在执行SQL", currentExecuteSqlMap != null ? currentExecuteSqlMap : "无");
            dataSourcesMap.put("datasource_" + index++, dataSourceMap);
        }
        return dataSourcesMap;
    }

    private Map<String, Object> getCurrentExecuteSqlMap(List<SqlExecuteContent> sqlExecuteContentList) {
        if (!sqlExecuteContentList.isEmpty()) {
            Map<String, Object> currentExecuteSqlMap = new LinkedHashMap<>();
            for (SqlExecuteContent sqlExecuteContent : sqlExecuteContentList) {
                Map<String, Object> sqlExecuteContentMap = new LinkedHashMap<>();
                sqlExecuteContentMap.put("sql-id", sqlExecuteContent.getSqlId());
                sqlExecuteContentMap.put("开始时间", sqlExecuteContent.getStartTime());
                sqlExecuteContentMap.put("已用时", sqlExecuteContent.getUsedTime() + "毫秒");
                currentExecuteSqlMap.put("sql_" + sqlExecuteContent.getSeq(), sqlExecuteContentMap);
            }
            return currentExecuteSqlMap;
        }
        return null;
    }

    @Override
    public String getModuleName() {
        return EasyMsDataSourceConstant.MODULE_NAME;
    }

    @Override
    public int getOrder() {
        return 1;
    }

}